﻿/*
 * 
 * Responsabilidade:
 * Gerenciar um diálogo byte, utilizando painel e porta
 * Fazer parte da camada bloqueiando exceções
 * 
 * Definição:
 * Em um diálogo byte, a unidade da transmissão e recepção é um byte.
 * A estrutura de telegramas é ignorada. Valores apaerçem só em hexadecimal.
 * A iniciativa para receber um byte é do usuário. 
 * Uso da exceção tempo limite esgotado prevê bloqueiar o diálogo.
 * 
 */

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO.Ports;
using System.Globalization;

namespace J_Controle
{
    public class DialogoByte : ControladorDialogo
    {

        public DialogoByte(Panel prmPanel) : base(prmPanel)
        {
        }

        public new bool Conectar(SerialPort prmPorta, ConfigHW prmCnf)
        {
            base.Conectar(prmPorta, prmCnf);
            try
            {
                PortaAtual.ReadTimeout = 20;  // 20 ms, independente do bps######################
                PortaAtual.DataReceived += (hanDadosAtual = (SerialDataReceivedEventHandler)OnDataReceived);
                PortaAtual.ErrorReceived += (hanErroAtual = (SerialErrorReceivedEventHandler)OnRxError);
                PortaAtual.PinChanged += (hanPinoAtual = (SerialPinChangedEventHandler)OnPinChanged);
                PortaAtual.Open();
                return true;
            }
            catch (Exception e)
            {
                MessageBox.Show(e.Message, "Exceção em DialogoByte.Conectar");
                return false;
            }
            finally
            {
                PortaAtual.DataReceived -= hanDadosAtual;
                PortaAtual.ErrorReceived -= hanErroAtual;
                PortaAtual.PinChanged -= hanPinoAtual;
                PortaAtual.Close();
            }
        }
        public void GravByte()
        {
            byte[] bb = new byte[1];
            string ss;

            // fiscalização do estado
            if (!PortaAtual.IsOpen)
            {
                MessageBox.Show("A porta serial não está aberta, operação cancelado.");
                return;
            }

            // conversão do string em hex
            ss = PainelAtual.Controls["textGrav"].Text;
            if (!Byte.TryParse(ss, NumberStyles.HexNumber, null, out bb[0]))
            {
                MessageBox.Show(ss + " " + "não é um hexadecimal legítimo.");
                return;
            }

            // gravação para a porta serial. Atualizar check box do tempo limite
            (PainelAtual.Controls["ckTlimGrav"] as CheckBox).Checked = false;
            try
            {
                PortaAtual.WriteTimeout = 20;  // 20 ms, independente do bps######################
                PortaAtual.Write(bb, 0, 1);
            }
            catch (TimeoutException)
            {
                (PainelAtual.Controls["ckTlimGrav"] as CheckBox).Checked = true;
            }
        }
        public void LerByte()
        {
            int bb;
            // fiscalização do estado
            if (!PortaAtual.IsOpen)
            {
                MessageBox.Show("A porta serial não está aberta, operação cancelado.");
                return;
            }
            // leitura da porta serial. Atualizar check box do tempo limite
            (PainelAtual.Controls["ckTlimLer"] as CheckBox).Checked = false;
            PainelAtual.Controls["textLer"].Text = "";
            try
            {
                bb = PortaAtual.ReadByte();

                PainelAtual.Controls["textLer"].Text = String.Format("{0:X2}", bb);
            }
            catch (TimeoutException)
            {
                (PainelAtual.Controls["ckTlimLer"] as CheckBox).Checked = true;
            }
        }
        public void OnRxError(Object sender, SerialErrorReceivedEventArgs e)
        {
            MessageBox.Show("Rx Error");
        }
        public void OnDataReceived(Object sender, SerialDataReceivedEventArgs d)
        {
            // used only because the absence of this handler is said to block the error handler
            //MessageBox.Show(String.Format("{0} bytes to read",PortaAtual.BytesToRead),"Data Received");
        }
        public void OnPinChanged(Object sender, SerialPinChangedEventArgs p)
        {
        }
    }
}
